package com.ziq.zcamp.util

import android.content.Context
import android.content.Intent
import android.net.Uri
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.*
import com.amap.api.services.poisearch.PoiSearch
import com.amap.api.services.route.DistanceItem
import com.amap.api.services.route.DistanceSearch
import com.ziq.zcamp.R
import com.ziq.zcamp.bean.place.LocationInfo
import com.ziq.zcamp.manager.GlobalContextManager
import kotlinx.coroutines.suspendCancellableCoroutine


class MapUtil {
    companion object {
        const val GAODE_MAP = "com.autonavi.minimap"
        const val BAIDU_MAP = "com.baidu.BaiduMap"
        const val TENCENT_MAP = "com.tencent.map"
        const val GOOGLE_MAP = "com.google.android.apps.maps"

        var lastTime = 0L
        var mAMapLocation: AMapLocation ?= null
        const val INTERVAL = 1000 * 60 * 10L

        fun openGaoDeGuide(context: Context, name: String, latitude :String, longitude :String) {
            try {
                val intent = Intent.getIntent(
                    "androidamap://navi?sourceApplication=${GlobalContextManager.getString(R.string.app_name)}" +
                            "&poiname=$name" +
                            "&lat=$latitude" +
                            "&lon=$longitude"+
                            "&dev=0"
                )
                GlobalContextManager.startActivity(context, intent)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        fun openBaiDuGuide(context: Context, name: String, latitude :String, longitude :String) {
            try {
                val latlng = GPSUtil.gcj02_To_Bd09(latitude.toDouble(), longitude.toDouble())
                val intent = Intent.getIntent(
                    "intent://map/direction?" +  //"origin=latlng:"+"34.264642646862,108.95108518068&" +   //起点  此处不传值默认选择当前位置
                            "destination=latlng:" + latlng[0] + "," + latlng[1] + "|name:$name" +  //终点
                            "&mode=driving" +  //导航路线方式
                            "&region=" +  //
                            "&src=" + GlobalContextManager.getString(R.string.app_name) +
                            "#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end"
                )
                GlobalContextManager.startActivity(context, intent)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        fun openTencentGuide(context: Context, name: String, latitude :String, longitude :String) {
            try {
                val tencnetUri: String =  "qqmap://map/routeplan?type=drive&from=&fromcoord=&to=$name&tocoord=$latitude,$longitude&policy=1&referer="+ GlobalContextManager.getString(R.string.app_name)
                val intent = Intent.getIntent(tencnetUri)
                GlobalContextManager.startActivity(context, intent)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        fun openGoogleGuide(context: Context, name: String, latitude :String, longitude :String) {
            try {
                val gmmIntentUri = Uri.parse("google.navigation:q=$latitude,$longitude")
                val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
                mapIntent.setPackage("com.google.android.apps.maps")
                GlobalContextManager.startActivity(context, mapIntent)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }


        fun getCurrentLocation(callback: (location: AMapLocation)->Unit, onFail: (()->Unit)? = null){
            try {
                val timeDifference = System.currentTimeMillis() - lastTime
                val m = mAMapLocation
                if (timeDifference<= INTERVAL && m!=null && m.errorCode == 0){
                    callback.invoke(mAMapLocation!!)
                    return
                }
                val locationClient = AMapLocationClient(GlobalContextManager.appContext!!)
                locationClient.setLocationListener {
                    mAMapLocation = it
                    lastTime = System.currentTimeMillis()
                    callback.invoke(it)
                    locationClient.onDestroy()
                }
                val locationClientOption = AMapLocationClientOption()
                locationClientOption.setOnceLocation(true)
                locationClientOption.setLocationCacheEnable(false)
                locationClient.setLocationOption(locationClientOption)
                locationClient.startLocation()
            }catch (e:Exception){
                onFail?.invoke()
                e.printStackTrace()
            }
        }

        //nearLeft farRight 需要配合 关键词
        fun poiSearch(query : PoiSearch.Query,
                      myLatLng: LatLonPoint? = null, radiusBound:Int = 6000,
                      callback: PoiSearch.OnPoiSearchListener, onFail: (()->Unit)? = null){
            try {
                val poiSearch = PoiSearch(GlobalContextManager.appContext!!, query)
                poiSearch.setOnPoiSearchListener(callback)
                if(myLatLng != null){
                    poiSearch.setBound(PoiSearch.SearchBound(myLatLng, radiusBound, true))
                }
                // 设置搜索区域为以lp点为圆心，其周围5000米范围
                poiSearch.searchPOIAsyn() // 异步搜索
            }catch (e:Exception){
                onFail?.invoke()
            }
        }

        suspend fun getLocation( latitude :String, longitude :String) : LocationInfo?{
            return suspendCancellableCoroutine {
                val geocoderSearch = GeocodeSearch(GlobalContextManager.appContext)
                geocoderSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
                    override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {
                        //解析result获取地址描述信息
                        if (rCode == 1000) {
                            val locationInfo = LocationInfo()
                            locationInfo.site = result?.regeocodeAddress?.formatAddress
                            locationInfo.latitude = latitude
                            locationInfo.longitude = longitude
                            locationInfo.adcode = result?.regeocodeAddress?.adCode
                            locationInfo.citycode = result?.regeocodeAddress?.cityCode
                            it.resumeWith(Result.success(locationInfo))
                        } else {
                            it.resumeWith(Result.success(null))
                        }
                    }

                    override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) {
                        it.resumeWith(Result.success(null))
                    }
                })
                val query = RegeocodeQuery(LatLonPoint(latitude.toDouble(), longitude.toDouble()), 200f, GeocodeSearch.AMAP)
                geocoderSearch.getFromLocationAsyn(query)
            }
        }


        suspend fun getLocationRegeocodeAddress( latitude :String, longitude :String) : RegeocodeAddress?{
            return suspendCancellableCoroutine {
                val geocoderSearch = GeocodeSearch(GlobalContextManager.appContext)
                geocoderSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
                    override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {
                        //解析result获取地址描述信息
                        if (rCode == 1000) {
                            it.resumeWith(Result.success(result?.regeocodeAddress))
                        } else {
                            it.resumeWith(Result.success(null))
                        }
                    }

                    override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) {
                        it.resumeWith(Result.success(null))
                    }
                })
                val query = RegeocodeQuery(LatLonPoint(latitude.toDouble(), longitude.toDouble()), 1000f, GeocodeSearch.AMAP)
                query.extensions = GeocodeSearch.EXTENSIONS_ALL
                geocoderSearch.getFromLocationAsyn(query)
            }
        }


        fun calculateRouteDistanceAsyn(context: Context,distanceStart :LatLonPoint?,distanceEnd:LatLonPoint?,callback: (item: DistanceItem?) -> Unit){
            if(distanceStart != null && distanceEnd != null){
                val distanceSearch = DistanceSearch(context)
                distanceSearch.setDistanceSearchListener { distanceResult, _ ->
                    val distanceItem = distanceResult?.distanceResults?.get(0)
                    callback.invoke(distanceItem)
                }

                val latLonPoints: MutableList<LatLonPoint> = ArrayList()
                latLonPoints.add(distanceStart)
                val distanceQuery = DistanceSearch.DistanceQuery()
                distanceQuery.origins = latLonPoints
                distanceQuery.destination = distanceEnd
                //设置测量方式，支持直线和驾车
                distanceQuery.type = DistanceSearch.TYPE_DISTANCE
                distanceSearch.calculateRouteDistanceAsyn(distanceQuery)
            }
        }

        fun getDirection(direction : String) : String{
            return when(direction){
                "东" -> "西"
                "南" -> "北"
                "西" -> "东"
                "北" -> "南"
                "东北" -> "西南"
                "东南" -> "西北"
                "西南" -> "东北"
                "西北" -> "东南"
                else -> ""
            }
        }
    }
}